package com.kingyea.mobilepolice.apimanage.serviceinfo.service.impl;

import com.alibaba.fastjson.JSON;
import com.kingyea.mobilepolice.apimanage.dictionary.service.DictionaryService;
import com.kingyea.mobilepolice.apimanage.paraminfo.bean.ParamInfo;
import com.kingyea.mobilepolice.apimanage.paraminfo.service.ParamInfoService;
import com.kingyea.mobilepolice.apimanage.responseinfo.bean.ResponseInfo;
import com.kingyea.mobilepolice.apimanage.responseinfo.service.ResponseInfoService;
import com.kingyea.mobilepolice.apimanage.servicehistory.bean.ServiceHistory;
import com.kingyea.mobilepolice.apimanage.servicehistory.service.ServiceHistoryService;
import com.kingyea.mobilepolice.apimanage.serviceinfo.bean.ServiceInfo;
import com.kingyea.mobilepolice.apimanage.serviceinfo.dao.ServiceInfoMapper;
import com.kingyea.mobilepolice.apimanage.serviceinfo.service.ServiceInfoService;
import com.kingyea.mobilepolice.apimanage.serviceinfo.vo.ServiceInfoVO;
import com.kingyea.mobilepolice.apimanage.systemsync.Send2Queue;
import com.kingyea.mobilepolice.apimanage.utils.NumberUtils;
import com.kingyea.mobilepolice.apimanage.utils.StateCode;
import com.kingyea.mobilepolice.apimanage.utils.page.PageInfo;
import com.kingyea.mobilepolice.dictionary.bean.Dictionary;
import com.kingyea.mobilepolice.system.exception.BusinessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author Mr.Lin
 * @version v1.0.0
 * @description ServiceInfo 实现类
 * @date Created in 2018-03-02 16:37:14
 */
@Service
@Transactional
public class ServiceInfoServiceImpl implements ServiceInfoService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ServiceInfoServiceImpl.class);
    @Autowired
    DictionaryService dictionaryService;
    @Resource
    private ServiceInfoMapper serviceInfoMapper;
    @Autowired
    private ParamInfoService paramInfoService;
    @Autowired
    private ResponseInfoService responseInfoService;
    @Autowired
    private ServiceHistoryService serviceHistoryService;

    /**
     * 通过ID查找对象
     *
     * @param id
     * @return
     */
    @Override
    public ServiceInfo getById(Integer id) throws Exception {
        return this.serviceInfoMapper.getById(id);
    }

    @Override
    public ServiceInfo getBySerialNo(String serialNo) throws Exception {
        return serviceInfoMapper.getBySerialNo(serialNo);
    }

    /**
     * 列表
     *
     * @param
     * @return
     */
    @Override
    public List<ServiceInfo> list(ServiceInfo serviceInfo) throws Exception {
        List<ServiceInfo> list = serviceInfoMapper.list(serviceInfo);
        return list;
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    @Send2Queue
    @Override
    public int deleteById(Integer id) throws Exception {
        if (NumberUtils.isNullOrLEZero(id)) {
            throw new BusinessException(StateCode.ILLEGAL_ARGUMENT_ERROR);
        }
        // 作关删除
        paramInfoService.deletesByServiceId(id);
        responseInfoService.deletesByServiceId(id);
        serviceInfoMapper.deleteById(id);
        return 1;
    }

    /**
     * 保存
     *
     * @param serviceInfo
     * @return
     */
    @Send2Queue
    @Override
    public ServiceInfo save(ServiceInfo serviceInfo) throws Exception {
        try {
            serviceInfoMapper.save(serviceInfo);
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
        return serviceInfo;
    }

    /**
     * 保存
     *
     * @param serviceInfoVO
     * @return
     */
    @Send2Queue
    @Override
    public ServiceInfoVO saveVO(ServiceInfoVO serviceInfoVO) throws Exception {
        // 参数检查
        if (StringUtils.isEmpty(serviceInfoVO.getName()) || StringUtils.isEmpty(serviceInfoVO.getPath())
                || StringUtils.isEmpty(serviceInfoVO.getPublicPath()) || StringUtils.isEmpty(serviceInfoVO.getServiceAddress())) {
            throw new BusinessException(StateCode.NO_ARGUMENT_ERROR);
        }
        // todo 对外地址+请求方式 还需要判断是否重复
        ServiceInfo queryServiceInfo = new ServiceInfo();
        queryServiceInfo.setSerialNo(serviceInfoVO.getSerialNo());
        List<ServiceInfo> isExistList = serviceInfoMapper.list(queryServiceInfo);
        if (isExistList != null && isExistList.size() > 0) {
            throw new BusinessException(StateCode.UNIQUE_IDENTIFIER_EXIST);
        }
        serviceInfoMapper.save(serviceInfoVO);
        List<ParamInfo> paramInfos = serviceInfoVO.getParamInfos();
        if (paramInfos != null && paramInfos.size() > 0) {
            for (ParamInfo paramInfo : paramInfos) {
                ParamInfo isExistParam = paramInfoService.getByNameAndServiceId(paramInfo.getName(), paramInfo.getServiceId());
                if (isExistParam != null) {
                    throw new BusinessException(StateCode.SERVER_DATA_DUPLICATE_ERROR);
                }
                paramInfo.setServiceId(serviceInfoVO.getId());
                paramInfoService.save(paramInfo);
            }
        }

        List<ResponseInfo> responseInfos = serviceInfoVO.getResponseInfos();
        if (responseInfos != null && responseInfos.size() > 0) {
            for (ResponseInfo responseInfo : responseInfos) {
                ResponseInfo isExistResp = responseInfoService.getByNameAndServiceId(responseInfo.getName(), responseInfo.getServiceId());
                if (isExistResp != null) {
                    throw new BusinessException(StateCode.SERVER_DATA_DUPLICATE_ERROR);
                }
                responseInfo.setServiceId(serviceInfoVO.getId());
                responseInfoService.save(responseInfo);
            }
        }
        return serviceInfoVO;
    }

    /**
     * 更新  唯一标识可能是不允许修改???
     *
     * @param serviceInfo
     * @return
     */
    @Send2Queue
    @Override
    public ServiceInfo update(ServiceInfo serviceInfo) throws Exception {
        try {
            // 参数检查
            if (StringUtils.isEmpty(serviceInfo.getName()) || StringUtils.isEmpty(serviceInfo.getId())
                    || StringUtils.isEmpty(serviceInfo.getSerialNo()) || StringUtils.isEmpty(serviceInfo.getPath())
                    || StringUtils.isEmpty(serviceInfo.getPublicPath()) || StringUtils.isEmpty(serviceInfo.getServiceAddress())) {
                throw new BusinessException(StateCode.NO_ARGUMENT_ERROR);
            }
            // todo 对外地址+请求方式 还需要判断是否重复
            ServiceInfo serviceInfoOld = getById(serviceInfo.getId());
            if (serviceInfoOld == null) {
                throw new BusinessException(StateCode.SERVER_DATA_MISSING_ERROR);
            }
            if (!serviceInfoOld.getSerialNo().equals(serviceInfo.getSerialNo())) {// 修改了唯一标识
                // 查询是否存在其它记录是使用该标识符
                List<ServiceInfo> isExisList = serviceInfoMapper.getBySerialNoAndExcludeID(serviceInfo.getSerialNo(), serviceInfo.getId());
                if (isExisList != null && isExisList.size() > 0) {
                    throw new BusinessException(StateCode.UNIQUE_IDENTIFIER_EXIST);
                }
            }
            if (!serviceInfoOld.getVersion().equals(serviceInfo.getVersion())) {// 修改了版本号
                // serviceHistoryMapper 检查 version 是否存在 serviceHistory ，存在则不能插入
                ServiceHistory serviceHistoryExist = serviceHistoryService.getById(serviceInfo.getSerialNo(), serviceInfo.getVersion());
                if (serviceHistoryExist != null) {
                    throw new BusinessException(StateCode.VERSION_EXIST);
                }
                // 保存旧版本
                ServiceInfoVO serviceInfoVO = getFullVoById(serviceInfoOld.getId());
                ServiceHistory serviceHistory = new ServiceHistory();
                serviceHistory.setServiceSerialNo(serviceInfoVO.getSerialNo());
                serviceHistory.setVersion(serviceInfoVO.getVersion());
                serviceHistory.setCreateById(serviceInfoVO.getCreateById());
                //serviceHistory.setCreateByName(serviceInfoVO.getCreateByName());// todo 插入创建者名称
                serviceHistory.setCreateTime(serviceInfoVO.getCreateTime());
                serviceHistory.setJson(JSON.toJSONString(serviceInfoVO));
                serviceHistoryService.save(serviceHistory);
            }
            serviceInfoMapper.update(serviceInfo);
        } catch (Throwable e) {
            System.out.println(">>>" + e.getMessage());
            e.printStackTrace();
            throw e;
        }
        return serviceInfo;
    }

    /**
     * 根据ID 获取完整接口对象，包括出入参数
     *
     * @param id
     * @return com.kingyea.mobilepolice.apimanage.serviceinfo.vo.ServiceInfoVO
     * @author Mr.Lin
     * @date 2018/5/5 18:15
     */
    @Override
    public ServiceInfoVO getFullVoById(Integer id) {
        return serviceInfoMapper.getFullVoById(id);
    }

    @Override
    public Object searchServiceAndProvider(Map<String, Object> map) throws Exception {
        PageInfo.startPage(map);
        return PageInfo.getPageInfo(serviceInfoMapper.searchServiceAndProvider(map));
    }

    @Override
    public PageInfo<ServiceInfoVO> searchByCondition(Map<String, Object> map) throws Exception {
        String mapKey_policeType = "policeType";
        if (map.containsKey(mapKey_policeType) && !StringUtils.isEmpty(map.get(mapKey_policeType))) {
            Integer[] policeType = JSON.parseObject(JSON.toJSONString(map.get(mapKey_policeType)), Integer[].class);
            List<Integer> querySub = new ArrayList<>();
            for (Integer integer : policeType) {
                List<Dictionary> subList = dictionaryService.getSubNodeListByPid(new HashMap<String, Integer>() {{
                    put("pid", integer);
                }});
                subList = JSON.parseArray(JSON.toJSONString(subList), Dictionary.class);
                for (Dictionary dictionary : subList) {
                    querySub.add(dictionary.getId());
                }
            }
            querySub.addAll(Arrays.asList(policeType));// 每个节点的所有子节点+自己  用来作参数  *当只有父节点的时候
            map.put(mapKey_policeType, querySub);
        }
        PageInfo.startPage(map);
        return PageInfo.getPageInfo(serviceInfoMapper.searchByCondition(map));
    }

    @Send2Queue
    @Override
    public int changeOnLineStatus(Map<String, Object> map) {
        if (!map.containsKey("id")) {
            throw new BusinessException(StateCode.NO_ARGUMENT_ERROR);
        }
        Integer id = NumberUtils.obj2Int(map.get("id"));
        return serviceInfoMapper.changeOnLineStatus(map);
    }

    @Send2Queue
    @Override
    public Object updateVO(ServiceInfoVO serviceInfoVO) throws Exception {
        update(serviceInfoVO);
        List<ParamInfo> paramInfos = serviceInfoVO.getParamInfos();
        // 检查两组子对象是否都有 serviceIn的ID
        for (ParamInfo paramInfo : paramInfos) {
            if (NumberUtils.isLEZeroNumObj(paramInfo.getServiceId())) {
                paramInfo.setServiceId(serviceInfoVO.getId());
            }
        }
        List<ResponseInfo> responseInfos = serviceInfoVO.getResponseInfos();
        for (ResponseInfo responseInfo : responseInfos) {
            if (NumberUtils.isNullOrLEZero(responseInfo.getServiceId())) {
                responseInfo.setServiceId(serviceInfoVO.getId());
            }
        }

        /** 查询原来的子对象，对比后作相应删除操作 */
        ServiceInfoVO originaObj = serviceInfoMapper.getVOById(serviceInfoVO.getId());
        List<ParamInfo> originaParamInfos = originaObj.getParamInfos();
        List<ResponseInfo> originaResponseInfos = originaObj.getResponseInfos();

        for (ParamInfo originaParamInfo : originaParamInfos) {
            boolean isNeedDel = true;
            for (ParamInfo paramInfo : paramInfos) {
                if (isNeedDel) {
                    if (paramInfo.getServiceId().intValue() == originaParamInfo.getServiceId().intValue() && paramInfo.getName().equals(originaParamInfo.getName())) {
                        isNeedDel = false;// 只要原来的子对象 存在 修改提交后的子对象列表里，就不需要删除
                    }
                }
            }
            if (isNeedDel) {
                paramInfoService.deleteById(originaParamInfo.getId());
            }
        }

        for (ResponseInfo originaResponseInfo : originaResponseInfos) {
            boolean isNeedDel = true;
            for (ResponseInfo responseInfo : responseInfos) {
                if (isNeedDel) {
                    if (responseInfo.getServiceId().intValue() == originaResponseInfo.getServiceId().intValue() && responseInfo.getName().equals(originaResponseInfo.getName())) {
                        isNeedDel = false;// 只要原来的子对象 存在 修改提交后的子对象列表里，就不需要删除
                    }
                }
            }
            if (isNeedDel) {
                responseInfoService.deleteById(originaResponseInfo.getId());
            }
        }

        // 更新param子对象操作
        if (paramInfos != null && paramInfos.size() > 0) {
            for (ParamInfo paramInfo : paramInfos) {
                ParamInfo isExistParam = paramInfoService.getByNameAndServiceId(paramInfo.getName(), paramInfo.getServiceId());
                if (isExistParam != null) {//更新
                    paramInfoService.update(paramInfo);
                } else {
                    paramInfoService.save(paramInfo);
                }
            }
        }

        // 更新response子对象操作
        if (responseInfos != null && responseInfos.size() > 0) {
            for (ResponseInfo responseInfo : responseInfos) {
                ResponseInfo isExistResp = responseInfoService.getByNameAndServiceId(responseInfo.getName(), responseInfo.getServiceId());
                if (isExistResp != null) {//更新
                    responseInfoService.update(responseInfo);
                } else {
                    responseInfoService.save(responseInfo);
                }
            }
        }
        return serviceInfoVO;
    }

    @Send2Queue
    @Override
    public Object check(Map<String, Object> map) throws Exception {
        if (!map.containsKey("id") || !map.containsKey("status") || StringUtils.isEmpty(map.get("status")) || NumberUtils.isNullOrLEZero(map.get("id"))) {
            throw new BusinessException(StateCode.NO_ARGUMENT_ERROR);
        }
        String status = map.get("status").toString();
        if (!status.equals("3") && !status.equals("4")) {
            throw new BusinessException(StateCode.ILLEGAL_ARGUMENT_ERROR);
        }
        ServiceInfo serviceObj = new ServiceInfo();
        serviceObj.setId(NumberUtils.obj2Int(map.get("id")));
        serviceObj.setStatus(NumberUtils.obj2Int(map.get("status")));
        serviceObj.setAuditTime(new Date());
        serviceInfoMapper.update(serviceObj);
        return 1;
    }

    /**
     * 带条件统计接口数量
     */
    @Override
    public Integer countByCondition(Map<String, Object> map) {

        return serviceInfoMapper.countByCondition(map);
    }

    @Override
    public Object countAllService(Map<String, Object> map) throws Exception {
        PageInfo.startPage(map);
        return PageInfo.getPageInfo(serviceInfoMapper.countAllService(map));
    }

    @Override
    public Object countTodayService(Map<String, Object> map) throws Exception {
        PageInfo.startPage(map);
        return PageInfo.getPageInfo(serviceInfoMapper.countTodayService(map));
    }

    @Override
    public Object serviceInfoCountByLoction(Map<String, Object> map) throws Exception {
        PageInfo.startPage(map);
        return PageInfo.getPageInfo(serviceInfoMapper.serviceInfoCountByLoction(map));
    }

    @Override
    public void requesterCountTask(Map<String, Object> map) {
        serviceInfoMapper.requesterCountTask(map);
    }

}
